﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Xna.Framework;
using TopShooter.Items;

namespace TopShooter.Editor
{
	public partial class EditorWindow : Form
	{
		static public EditorWindow Instance { get; private set; }

		static public void ShowEditor()
		{
			if (Instance == null)
			{
				EditorWindow ew = new EditorWindow();
				ew.Show();
			}
		}

		public EditorWindow()
		{
			Instance = this;
			InitializeComponent();

			Entity.SelectionManager.EntitySelected += new Action<Entity.SelectionManager, Entity>(SelectionManager_EntitySelected);
			Entity.SelectionManager.EntityDeselected += new Action<Entity.SelectionManager, Entity>(SelectionManager_EntityDeselected);
			InputHandler.MouseIsNowOverscreen += new Action(InputHandler_MouseIsNowOverscreen);
		}

		void InputHandler_MouseIsNowOverscreen()
		{
			gamePanel.Focus();
		}

		void SelectionManager_EntityDeselected(Entity.SelectionManager selections, Entity entity)
		{
		}

		void SelectionManager_EntitySelected(Entity.SelectionManager selections, Entity entity)
		{
			objectPropertyGrid.SelectedObject = entity;
		}

		public RenderControls.GameDraw GameView { get { return gamePanel; } }

		protected override void OnShown(EventArgs e)
		{
			base.OnShown(e);
			objectSelectBox.SelectedIndex = 0;
			SetTileByName(objectSelectBox.Text);
			InputHandler.Instance.RegisterForMouseEvent(this, MouseEventTypes.WheelChanged, TopShooter.MouseButtons.None, KeyboardModes.Normal, _ChangeBrushSize);

			_PopulateAppTree();
		}

		protected override void OnClosed(EventArgs e)
		{
			if (Instance == this)
				Instance = null;

			base.OnClosed(e);
		}

		private void selectSceneToolStripMenuItem_Click(object sender, EventArgs e)
		{

		}

		private void saveProjectToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Scene.Instance.SaveIfNeeded();
		}

		private void addNewSceneToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Scene.Manager.Instance.LoadNewScene();
		}

		private void deleteThisSceneToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Scene.Manager.Instance.DeleteCurrentScene();
		}

		private void clearThisSceneToolStripMenuItem_Click(object sender, EventArgs e)
		{

		}

		private void pauseButton_Click(object sender, EventArgs e)
		{
			if (Game.IsEditorMode == false)
			{
			}
		}

		private void stopButton_Click(object sender, EventArgs e)
		{
			Game.IsEditorMode = true;
			Scene.DynamicContentRegistry.Clear();
			Game.Instance.ReloadCurrentScene(false);
			//Controls.EditorWindow.ShowEditor();
		}


		private int _PromptUserForPortalID()
		{
			return 0;
		}
		private Tile GetTileByName(string name)
		{
			switch (name)
			{
				case "None": return null;
				case "Floor": return Assets.Tiles.Floor;
				case "Wall": return Assets.Tiles.Wall;
				case "Portal":
					int id = _PromptUserForPortalID();
					return new Portal(id, "Tiles/Portal_1", null);

				case "Secret Door": return Assets.Tiles.SecretDoor;
				case "Map Expander": return Assets.Tiles.MapExpander;
				default: return null;
			}
		}
		private void SetTileByName(string name)
		{
			Tile tile = GetTileByName(name);
			Editor.GameEditorPlayer.BrushTile = tile;
		}
		private Entity GetEntityByName(string name)
		{
			switch (name)
			{
				case "None": return null;
				case "Barrel": return Assets.Entities.Barrel;
				case "Infantry1": return new Units.Infantry(1, Assets.Weapons.Spear.Clone() as Weapon);
				case "Infantry2": return new Units.Infantry(2, Assets.Weapons.Spear.Clone() as Weapon);
				case "SpearThrower1": return new Units.Infantry(1, Assets.Weapons.ThrowingSpear.Clone() as Weapon);
				case "SpearThrower2": return new Units.Infantry(2, Assets.Weapons.ThrowingSpear.Clone() as Weapon);
				default: return null;
			}
		}
		private void SetEntityByName(string name)
		{
			Entity e = GetEntityByName(name);
			Editor.GameEditorPlayer.BrushEntity = e;
		}

		private void objectSelectBox_SelectedIndexChanged(object sender, EventArgs e)
		{
			SetTileByName(objectSelectBox.Text);
			SetEntityByName(objectSelectBox.Text);
			gamePanel.Focus();
		}

		private void _ChangeBrushSize(MouseEvent evt)
		{
			Brush.Diameter = (int)MathHelper.Clamp(Brush.Diameter + evt.WheelDelta, 1, 12);
		}

		public Editor.Brush Brush = new Editor.Brush();

		private void renameSceneToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Scene.Manager.Instance.RenameCurrentScene();
		}

		private void sceneToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
		{
			this.selectSceneToolStripMenuItem.DropDownItems.Clear();

			List<string> Scenes = new List<string>(Scene.Manager.Instance.SceneNames);
			_AddScenes(Scenes, this.selectSceneToolStripMenuItem, "");

		}

		private string _StripFolder(string Scene, out string folderName)
		{
			int indexOfDot = Scene.IndexOf('.');
			if (indexOfDot >= 1 && indexOfDot != (Scene.Length - 1))
			{
				folderName = Scene.Substring(0, indexOfDot);
				return Scene.Substring(indexOfDot + 1);
			}

			folderName = "_FAILED";
			return Scene.Replace(".", "_FAILED_");
		}

		private void _AddScenes(List<string> Scenes, System.Windows.Forms.ToolStripMenuItem parentItem, string folderPath)
		{
			string currentFolder = "";
			List<string> folderFiles = new List<string>();

			for (int i = 0; i < Scenes.Count; i++)
			{
				string ln = Scenes[i];

				if (ln.Contains('.'))
				{	// in a folder
					string newFolderName;
					string newFileName = _StripFolder(ln, out newFolderName);

					if (newFolderName != currentFolder)
					{
						_AddFolder(currentFolder, folderFiles, parentItem, folderPath);
					}
					currentFolder = newFolderName;
					folderFiles.Add(newFileName);
				}
				else
				{	// not in a folder
					_AddFolder(currentFolder, folderFiles, parentItem, folderPath);

					string fullName = folderPath + ln;
					System.Windows.Forms.ToolStripMenuItem item = new System.Windows.Forms.ToolStripMenuItem();
					item.Name = fullName;
					item.Size = new System.Drawing.Size(158, 22);
					item.Text = ln;
					item.Click += new EventHandler(item_Click);
					parentItem.DropDownItems.Add(item);
				}
			}
			_AddFolder(currentFolder, folderFiles, parentItem, folderPath);

			Scenes.Clear();
		}
		private void _AddFolder(string folderName, List<string> contents, System.Windows.Forms.ToolStripMenuItem parentItem, string folderPath)
		{
			if (contents.Count == 0)
				return;

			System.Windows.Forms.ToolStripMenuItem folderItem = new System.Windows.Forms.ToolStripMenuItem();
			folderItem.Name = folderName;
			folderItem.Size = new System.Drawing.Size(158, 22);
			folderItem.Text = folderName;
			//folderItem.Click += new EventHandler(item_Click);
			parentItem.DropDownItems.Add(folderItem);

			_AddScenes(contents, folderItem, folderPath + folderName + ".");

		}

		void item_Click(object stupiditem, EventArgs e)
		{
			var item = stupiditem as System.Windows.Forms.ToolStripMenuItem;
			Portal.PortalTarget pd = new Portal.PortalTarget(item.Name + ",0,W");
			Scene.Manager.Instance.LoadSceneByName(item.Name, pd);
		}

		private void runButton_Click_1(object sender, EventArgs e)
		{
			Game.IsEditorMode = false;
			Scene.DynamicContentRegistry.Clear();
			Scene.Instance.Dispose();
			Game.Instance.ReloadCurrentScene(false);
		}

		private void _PopulateAppTree()
		{
			appTree.Nodes.Clear();
			appTree.Nodes.Add("Scenes");

			List<string> Scenes = new List<string>(Scene.Manager.Instance.SceneNames);
			_AddScenes(Scenes, appTree.TopNode, "");
		}

		private void _AddScenes(List<string> Scenes, TreeNode parentNode, string folderPath)
		{
			string currentFolder = "";
			List<string> folderFiles = new List<string>();

			for (int i = 0; i < Scenes.Count; i++)
			{
				string ln = Scenes[i];

				if (ln.Contains('.'))
				{	// in a folder
					string newFolderName;
					string newFileName = _StripFolder(ln, out newFolderName);

					if (newFolderName != currentFolder)
					{
						_AddSceneFolder(currentFolder, folderFiles, parentNode, folderPath);
					}
					currentFolder = newFolderName;
					folderFiles.Add(newFileName);
				}
				else
				{	// not in a folder
					_AddSceneFolder(currentFolder, folderFiles, parentNode, folderPath);

					string fullName = folderPath + ln;
					TreeNode node = new TreeNode();
					node.Name = fullName;
					//node.Size = new System.Drawing.Size(158, 22);
					node.Text = ln;
					node.Tag = new object();
					//node.Click += new EventHandler(item_Click);
					parentNode.Nodes.Add(node);
				}
			}
			_AddSceneFolder(currentFolder, folderFiles, parentNode, folderPath);

			Scenes.Clear();
		}

		private void _AddSceneFolder(string folderName, List<string> contents, TreeNode parentNode, string folderPath)
		{
			if (contents.Count == 0)
				return;

			TreeNode folderNode = new TreeNode();
			folderNode.Name = folderName;
			//folderNode.Size = new System.Drawing.Size(158, 22);
			folderNode.Text = folderName;
			//folderItem.Click += new EventHandler(item_Click);
			parentNode.Nodes.Add(folderNode);

			_AddScenes(contents, folderNode, folderPath + folderName + ".");

		}

		private void appTree_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
		{
			if (e.Button == System.Windows.Forms.MouseButtons.Left && e.Node.Tag != null)
			{
				Portal.PortalTarget pd = new Portal.PortalTarget(e.Node.Name + ",0,W");
				Scene.Manager.Instance.LoadSceneByName(e.Node.Name, pd);
				gamePanel.Focus();
			}
		}


	}
}
